package pt.mauromad.guias.dao;

import static java.lang.String.format;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import pt.mauromad.guias.dao.generic.GenericDao;
import pt.mauromad.guias.dao.security.RoleDao;

/**
 * @author pedro.amaral
 * 
 */
@Entity
@Table(name = "user")
public class UserDao extends GenericDao {
	private DomainDao domain;
	private String username;
	private String password;
	private String firstName;
	private String lastName;
	private Set<RoleDao> roles = new HashSet<>();

	@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH, optional = false)
	@JoinColumn(name = "domain_id", insertable = true, updatable = false, nullable = false)
	public DomainDao getDomain() {
		return domain;
	}

	public void setDomain(DomainDao domain) {
		this.domain = domain;
	}

	@Column(nullable = false)
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Column(nullable = false)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Column(nullable = false)
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	@Column(nullable = false)
	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@JoinTable(name = "user_roles", joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "role", nullable = false, updatable = false) })
	public Set<RoleDao> getRoles() {
		return roles;
	}

	public void setRoles(Set<RoleDao> roles) {
		this.roles = roles;
	}

	@Transient
	public String getFullName() {
		return format("%s %s", firstName, lastName);
	}

	@Transient
	public boolean hasRole(RoleDao role) {
		return roles.contains(role);
	}

	@Transient
	public boolean isEnabled() {
		return hasRole(RoleDao.ROLE_USER);
	}

	@Transient
	public boolean isAdministrator() {
		return hasRole(RoleDao.ROLE_ADMIN);
	}
}
